﻿using Kinlo.MESDocking;
using Kinlo.MESDocking.MQTT;
using Kinlo.MESDocking.MQTT.MQTTMessModels;
using MaterialDesignThemes.Wpf;
using Microsoft.Xaml.Behaviors.Layout;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UIWindows.Attributes;
using UIWindows.Domains;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Models;
using UIWindows.Models.Devices;
using UIWindows.Services.Handle;
using UIWindows.Tools.Helper;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.Services
{
    public class TaskService
    {
        private CancellationTokenSource _taskToken;
        private Dictionary<string, object> _tasks = default;
        private ConcurrentDictionary<string, object> _taskcd = default;
        #region 单例模式
        private static readonly object _lock = new object();
        private static TaskService taskService = default;

        public static TaskService Instance
        {
            get
            {
                if (taskService == null)
                {
                    lock (_lock)
                    {
                        if (taskService == null)
                        {
                            taskService = new TaskService();
                        }
                    }
                }
                return taskService;
            }
        }
        #endregion
        private SystemConfigStatic _systemConfigStatic;
        private DeviceConfigStatic _deviceConfig;
        private TemporaryStatic _temporaryStatic;
        private ParameterStatic _parameterStatic;

        private UserConfigStatic _userConfigStatic;
        private HomeStatic _homeStatic;
        Action<string, string, string, string, string, long, DateTime, string, string, string, string> _log;
        private TaskService()
        {
            _taskToken = new CancellationTokenSource();
            _tasks = new Dictionary<string, object>();
            _taskcd = new ConcurrentDictionary<string, object>();
            _systemConfigStatic = ObjectContainer.ResolveSingleton<SystemConfigStatic>();
            _deviceConfig = ObjectContainer.ResolveSingleton<DeviceConfigStatic>();
            _temporaryStatic = ObjectContainer.ResolveSingleton<TemporaryStatic>();
            _parameterStatic = ObjectContainer.ResolveSingleton<ParameterStatic>();

            _userConfigStatic = ObjectContainer.ResolveSingleton<UserConfigStatic>();
            _homeStatic = Domains.ObjectContainer.ResolveSingleton<HomeStatic>();
            _log = DialogLogHelper.MesLog;
        }

        private void InitTask()
        {
            _temporaryStatic.DeviceStatus.Clear();
            _tasks.Clear();
            foreach (var signal in _systemConfigStatic.SignalList)
            {
                _temporaryStatic.DeviceStatus.Add(signal.Name, 0);
                var iAddressList = _systemConfigStatic.IAddressList.Where(x => x.ServiceName == signal.Name);
                foreach (var item in iAddressList)
                {
                    var handlerType = typeof(Context.DataContext);
                    object? obj = Activator.CreateInstance(handlerType);
                    var objProper = handlerType.GetProperties();
                    objProper.Where(x => x.Name == "TaskType").FirstOrDefault()?.SetValue(obj, item.TaskType);
                    objProper.Where(x => x.Name == "DeviceType").FirstOrDefault()?.SetValue(obj, item.DeviceType);
                    objProper.Where(x => x.Name == "AddressingMethod").FirstOrDefault()?.SetValue(obj, signal.AddressingMethod);
                    objProper.Where(x => x.Name == "Address_Signal").FirstOrDefault()?.SetValue(obj, $"{signal.Address_Start}.{item.Label}");
                    objProper.Where(x => x.Name == "Address_Struct").FirstOrDefault()?.SetValue(obj, item.Address_Struct);
                    objProper.Where(x => x.Name == "Struct_Length").FirstOrDefault()?.SetValue(obj, item.Struct_Length);
                    objProper.Where(x => x.Name == "DeviceIndex").FirstOrDefault()?.SetValue(obj, item.DeviceIndex);
                    objProper.Where(x => x.Name == "ServiceName").FirstOrDefault()?.SetValue(obj, item.ServiceName);
                    _tasks.Add($"{signal.Name}{item.TaskType.GetHashCode()}{item.DeviceType.GetHashCode()}{item.Address_Struct}{item.DeviceIndex}", obj);
                }
            }
        }

        public async Task<bool> SwitchOn()
        {
            if (_taskToken.Token.IsCancellationRequested) { _taskToken = new CancellationTokenSource(); }
            if (await DeviceLink())
            {
                try
                {
                    _temporaryStatic.IsRunStatus = true;
                    _temporaryStatic.ExcisionList.Clear();
                    _temporaryStatic.IsExcision = System.Windows.Visibility.Collapsed;
                    InitTask();
                    foreach (var item in _systemConfigStatic.SignalList)
                    {
                        if (item.DeviceType == DeviceTypes.NONE)
                        {
                            continue;
                        }
                        var serviceList = _temporaryStatic.LinkList.FirstOrDefault(x => x.ServiceName == "上位机状态");
                        if (serviceList != null) { serviceList.Status = true; }
                        $"扫描线程 [{item.Name}] 启动".RunLog(MessageLevelType.信息);

                        if (item.Name != null && _parameterStatic.DecideParameter.EnableMES)
                        {
                            UpdateDeviceStatus(item.Name);
                            Tools.MesHelper.MesOeeHelper.OeeCapacity(_taskToken.Token, _temporaryStatic, _parameterStatic,
                               DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
                        }

                        #region 过程参数
                        if (_parameterStatic.DecideParameter.EnableMES)
                        {
                            _ = Task.Run(async () =>
                            {
                                try
                                {
                                    Stopwatch _stopwatch = new Stopwatch();
                                    string brokerAddress = "10.0.0.2";
                                    int port = 1883;

                                    //TOPIC：/aiipc/{工序编码}/{设备编码}
                                    string topic = $"/aiipc/{_parameterStatic.CollectionItemsParameter.TechnicsProcessCode}/{_parameterStatic.CollectionItemsParameter.EquipNum}";

                                    string message = "要发送的消息";
                                    var plc = _deviceConfig.DeviceList.FirstOrDefault(t => t.DeviceType == item.DeviceType && t.ServiceName == item.Name);
                                    if (plc == null) { return; }
                                    OmronCIP omronCIP = plc.Communication as OmronCIP;

                                    //循环压力 加压杠压力
                                    string[] valueArr = new string[]{
                                            "PC_Value[0]",
                                            "PC_Value[1]",
                                            "PC_Value[2]",
                                            "PC_Value[3]",
                                            "PC_Value[4]",
                                            "PC_Value[5]",
                                        };

                                    //测漏压力
                                    string[] vacuumArr = new string[]{
                                            "PC_Vacuum[0]",
                                            "PC_Vacuum[1]",
                                            "PC_Vacuum[2]",
                                            "PC_Vacuum[3]",
                                            "PC_Vacuum[4]",
                                            "PC_Vacuum[5]",
                                            "PC_Vacuum[6]",
                                            "PC_Vacuum[7]",
                                            "PC_Vacuum[8]",
                                            "PC_Vacuum[9]",
                                            "PC_Vacuum[10]",
                                            "PC_Vacuum[11]",
                                        };

                                    while (!_taskToken.Token.IsCancellationRequested)
                                    {
                                        try
                                        {
                                            //循环压力 加压杠压力
                                            var valueDataList = omronCIP.Read(valueArr, 7);
                                            //测漏压力
                                            var vacuumDataList = omronCIP.Read(vacuumArr, 13);

                                            if(valueDataList==null|| vacuumDataList==null)
                                            {
                                                continue;
                                            }

                                            //产出 产出=注液总数-多液数量-少液数量
                                            var Total_Output = _homeStatic.ChartData.Total_LiquidInjection - _homeStatic.ChartData.NG_MultiLiquid - _homeStatic.ChartData.NG_LessLiquid;
                                            //报废数量 报废=测漏数量+多液数量
                                            var Total_scrapped = _homeStatic.ChartData.NG_LeakDetection + _homeStatic.ChartData.NG_MultiLiquid;

                                            ProcessParameters messageData;
                                            if (_systemConfigStatic.SCM.MainDeviceType == MainDeviceTypeEnum.一次注液)
                                            {
                                                messageData = new ProcessParameters
                                                {
                                                    b = new ParametersData
                                                    {
                                                        rf = 5,
                                                        dl = new Dictionary<string, string>
                                                        {
                                                            { "ZY20001",$"{_parameterStatic.RangeParameter.WeighBeforeDown.ToString()}~{ _parameterStatic.RangeParameter.WeighBeforeUp.ToString()}"  }, // 注液前重量范围
                                                            { "ZY20002",$"{_parameterStatic.RangeParameter.QuantitativeDown.ToString()}~{ _parameterStatic.RangeParameter.QuantitativeUp.ToString()}" }, // 注液量范围
                                                            { "ZY20003", $"{_parameterStatic.RangeParameter.WeighAfterDown.ToString()}~{ _parameterStatic.RangeParameter.WeighAfterUp.ToString()}" }, // 注液后重量范围
                                                            { "ZY20004", valueDataList[0].ToString() }, // 循环压力1
                                                            { "ZY20005", valueDataList[1].ToString() }, // 循环压力2
                                                            { "ZY20006", valueDataList[2].ToString() }, // 循环压力3
                                                            { "ZY20007", valueDataList[3].ToString() }, // 循环压力4
                                                            { "ZY20008", valueDataList[4].ToString()}, // 循环压力5
                                                            { "ZY20009", valueDataList[5].ToString() }, // 循环压力6
                                                            { "ZY20010", vacuumDataList[0].ToString() }, // 测漏压力1
                                                            { "ZY20011", vacuumDataList[1].ToString() }, // 测漏压力2
                                                            { "ZY20012", vacuumDataList[2].ToString() }, // 测漏压力3
                                                            { "ZY20013", vacuumDataList[3].ToString() }, // 测漏压力4
                                                            { "ZY20014", vacuumDataList[4].ToString() }, // 测漏压力5
                                                            { "ZY20015", vacuumDataList[5].ToString() }, // 测漏压力6
                                                            { "ZY20016", vacuumDataList[6].ToString() }, // 测漏压力7
                                                            { "ZY20017", vacuumDataList[7].ToString() }, // 测漏压力8
                                                            { "ZY20018", vacuumDataList[8].ToString() }, // 测漏压力9
                                                            { "ZY20019", vacuumDataList[9].ToString() }, // 测漏压力10
                                                            { "ZY20020", vacuumDataList[10].ToString() }, // 测漏压力11
                                                            { "ZY20021", vacuumDataList[11].ToString() }, // 测漏压力12
                                                            { "ZY20022", _homeStatic.ChartData.Total_Inbound.ToString() }, // 投入量
                                                            { "ZY20023",Total_Output.ToString() }, // 产出量
                                                            { "ZY20024",Total_scrapped.ToString() }, // 报废量
                                                            { "ZY20025", _temporaryStatic.LinkList.FirstOrDefault(x => x.ServiceName == "设备状态")?.Status.ToString() }, // 设备状态
                                                            { "ZY20026", _userConfigStatic.LoginUser.Shift }, // 班次
                                                            { "ZY20027",_userConfigStatic.LoginUser.Name } // 操作员
                                                        }
                                                    },
                                                    ts = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz")
                                                };
                                            }
                                            else
                                            {
                                                messageData = new ProcessParameters
                                                {
                                                    b = new ParametersData
                                                    {
                                                        rf = 5,
                                                        dl = new Dictionary<string, string>
                                                        {
                                                            { "ZY20001",$"{_parameterStatic.RangeParameter.WeighBeforeDown.ToString()}~{ _parameterStatic.RangeParameter.WeighBeforeUp.ToString()}" }, // 注液前重量范围
                                                            { "ZY20002",$"{_parameterStatic.RangeParameter.QuantitativeDown.ToString()}~{ _parameterStatic.RangeParameter.QuantitativeUp.ToString()}" }, // 注液量范围
                                                            { "ZY20003",$"{_parameterStatic.RangeParameter.WeighAfterDown.ToString()}~{ _parameterStatic.RangeParameter.WeighAfterUp.ToString()}" }, // 注液后重量范围
                                                            { "ZY20004",$"{_parameterStatic.RangeParameter.QuantitativeDown.ToString()}~{ _parameterStatic.RangeParameter.QuantitativeUp.ToString()}" }, // 保有量范围(二次)
                                                            { "ZY20005", valueDataList[0].ToString() }, // 循环压力1
                                                            { "ZY20006", valueDataList[1].ToString() }, // 循环压力2
                                                            { "ZY20007", vacuumDataList[0].ToString() }, // 测漏压力1
                                                            { "ZY20008", vacuumDataList[1].ToString() }, // 测漏压力2
                                                            { "ZY20009", vacuumDataList[2].ToString() }, // 测漏压力3
                                                            { "ZY20010", vacuumDataList[3].ToString() }, // 测漏压力4
                                                            { "ZY20011", vacuumDataList[4].ToString() }, // 测漏压力5
                                                            { "ZY20012", vacuumDataList[5].ToString() }, // 测漏压力6
                                                            { "ZY20013", vacuumDataList[6].ToString() }, // 测漏压力7
                                                            { "ZY20014", vacuumDataList[7].ToString() }, // 测漏压力8
                                                            { "ZY20015", vacuumDataList[8].ToString() }, // 测漏压力9
                                                            { "ZY20016", vacuumDataList[9].ToString() }, // 测漏压力10
                                                            { "ZY20017", vacuumDataList[10].ToString() }, // 测漏压力11
                                                            { "ZY20018", vacuumDataList[11].ToString() }, // 测漏压力12
                                                            { "ZY20019", _homeStatic.ChartData.Total_Inbound.ToString() }, // 投入量
                                                            { "ZY20020", Total_Output.ToString() }, // 产出量
                                                            { "ZY20021", Total_scrapped.ToString()  }, // 报废量
                                                            { "ZY20022",  _temporaryStatic.LinkList.FirstOrDefault(x => x.ServiceName == "设备状态")?.Status.ToString() }, // 设备状态
                                                            { "ZY20023", _userConfigStatic.LoginUser.Shift }, // 班次
                                                            { "ZY20024", _userConfigStatic.LoginUser.Name }, // 操作员
                                                        }
                                                    },
                                                    ts = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz")
                                                };
                                            }


                                            message = JsonConvert.SerializeObject(messageData, Newtonsoft.Json.Formatting.Indented);

                                            _stopwatch.Restart();

                                            await MqttHelper.ConnectAndSendMessageAsync(brokerAddress, port, topic, message);

                                            _stopwatch.Stop();



                                            _log?.Invoke($"{topic}", "过程参数", "", message, "请求成功",
                                            _stopwatch.ElapsedMilliseconds, DateTime.Now,
                                            _parameterStatic.CollectionItemsParameter.EquipNum,
                                            _parameterStatic.CollectionItemsParameter.ProductType.ToString(),
                                            "MqttHelper", $"{brokerAddress}:{port}");

                                            //$"发送过程参数：topic=>{topic}\r\n{message}".RunLog(MessageLevelType.成功);
                                        }
                                        catch (Exception ex)
                                        {
                                            $"MQTT发送过程参数执行异常：{ex}".RunLog(MessageLevelType.错误);
                                        }
                                        finally
                                        {
                                            Thread.Sleep(1000);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    $"启动MQTT客户端：{ex}".RunLog(MessageLevelType.错误);
                                }


                            });
                        }

                        #endregion

                        _ = Task.Run(() =>
                        {
                            try
                            {
                                int count_Heartbeat = 0;
                                Models.Interact.ScanSignalModel ssModel = item;//扫描信号
                                bool[] bools = new bool[ssModel.Length_Resection];
                                var taskList = new Dictionary<string, object>();
                                foreach (var item in _tasks.Where(x => x.Key.Contains(ssModel.Name)))
                                {
                                    taskList.Add(item.Key, item.Value);
                                }
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
                                var plc = _deviceConfig.DeviceList.FirstOrDefault(t => t.DeviceType == ssModel.DeviceType && t.ServiceName == ssModel.Name);
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
                                if (plc == null) { return; }
                                OmronCIP omronCIP = plc.Communication as OmronCIP;
                                Models.Interact.PLCSignalModel signalData = new Models.Interact.PLCSignalModel(ssModel.Length_Signal, ssModel.Length_Resection);
                                StringBuilder key = new StringBuilder();
                                int count = 0;
                                while (!_taskToken.Token.IsCancellationRequested)
                                {
                                    try
                                    {
                                        if (omronCIP.ReadClass(ssModel.Address_Start, signalData) != null)
                                        {
                                            for (int i = 0; i < ssModel.Length_Signal; i++)
                                            {
                                                if (signalData.Cmd[i] == 1 || (signalData.Cmd[i] != _temporaryStatic.DeviceStatus[ssModel.Name] && i == 0))
                                                {
                                                    key.Clear();
                                                    var model = _systemConfigStatic.IAddressList.FirstOrDefault(x => x.Index == (i + 1) && x.ServiceName == ssModel.Name);
                                                    if (model != null)
                                                    {
                                                        if (model.TaskType == TaskTypes.设备状态)
                                                        {
                                                            //continue;
                                                            if (_temporaryStatic.DeviceStatus[ssModel.Name] == signalData.Cmd[i])
                                                            {
                                                                continue;
                                                            }
                                                            _temporaryStatic.DeviceStatus[ssModel.Name] = signalData.Cmd[i];
                                                        }
                                                        try
                                                        {
                                                            key.Append($"{model.ServiceName}{model.TaskType.GetHashCode()}{model.DeviceType.GetHashCode()}{model.Address_Struct}{model.DeviceIndex}");
                                                            if (_taskcd.ContainsKey(key.ToString()) || !_taskcd.TryAdd(key.ToString(), default)) { continue; }
                                                            TaskEventModel obj = ObjectContainer.ResolveEvent(model.TaskType);
                                                            object[] param = new object[] { taskList[key.ToString()] };
                                                            _ = Task.Run(() => obj?.Handle.Invoke(obj.TaskObject, param)).ConfigureAwait(false);
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            $"[{ssModel.Name}] [{model.TaskType}]信号触发异常：{ex}".RunLog(MessageLevelType.错误);
                                                        }
                                                    }
                                                }
                                            }
                                            for (int i = 0; i < ssModel.Length_Resection; i++)
                                            {
                                                if (signalData.Resection[i] && !bools[i])
                                                {
                                                    var resection = _systemConfigStatic.PLCResectionList.FirstOrDefault(x => x.ServiceName == ssModel.Name && x.Index == (i + 1));
                                                    if (resection != null)
                                                    {
                                                        resection.IsExcision = true;
                                                        $"[{ssModel.Name}] 注意：[{resection.Name}] 功能已启用！！！".RunLog(MessageLevelType.警告);
                                                        ThreadHelper.CrossThread(x => _temporaryStatic.ExcisionList.Add(resection), 0);
                                                    }
                                                }
                                                else if (!signalData.Resection[i] && bools[i])
                                                {
                                                    var resection = _systemConfigStatic.PLCResectionList.FirstOrDefault(x => x.ServiceName == ssModel.Name && x.Index == (i + 1));
                                                    if (resection != null)
                                                    {
                                                        resection.IsExcision = false;
                                                        $"[{ssModel.Name}] 注意：[{resection.Name}] 功能已关闭！！！".RunLog(MessageLevelType.成功);
                                                        ThreadHelper.CrossThread(x => _temporaryStatic.ExcisionList.Remove(resection), 0);
                                                    }
                                                }
                                                bools[i] = signalData.Resection[i];
                                            }
                                        }
                                        else
                                        {
                                            count += 1;
                                            if (count == 2)
                                            {
                                                $"[{ssModel.Name}] 连续扫描线程异常，退出任务！！！".RunLog(MessageLevelType.错误);
                                                _taskToken.Cancel();
                                                break;
                                            }
                                            Thread.Sleep(500);
                                            continue;
                                        }
                                        count_Heartbeat++;
                                        if (count_Heartbeat >= 20)
                                        {
                                            omronCIP.WriteSingle((short)1, ssModel.Heartbeat);
                                            count_Heartbeat = 0;
                                        }
                                        count = 0;
                                        _temporaryStatic.IsExcision = _temporaryStatic.ExcisionList.Count > 0 ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                                    }
                                    catch (Exception ex)
                                    {
                                        if (count == 2)
                                        {
                                            $"[{ssModel.Name}] 连续扫描信号异常，退出任务！！！".RunLog(MessageLevelType.错误);
                                            _taskToken.Cancel();
                                            break;
                                        }
                                        $"信号扫描线程异常：{ex}".RunLog(MessageLevelType.错误);
                                        count++;
                                        Thread.Sleep(500);
                                    }
                                    Thread.Sleep(20);
                                }
                                count = 0;
                                while (_taskcd.Count != 0)
                                {
                                    Thread.Sleep(500);
                                    if (count > 60)
                                    {
                                        _taskcd.Clear();
                                    }
                                    $"第 [{++count}] 次 等待所有任务退出.....".RunLog(MessageLevelType.警告);
                                }
                            }
                            catch (Exception ex)
                            {
                                $"扫描线程执行异常：{ex}".RunLog(MessageLevelType.错误);
                            }
                        }, _taskToken.Token).ContinueWith(sender =>
                        {
                            //退出扫描线程后的任务
                            _taskcd.Clear();
                            _temporaryStatic.IsRunStatus = false;
                            CloseDevice();
                            ThreadHelper.CrossThread(x =>
                            {
                                if (_systemConfigStatic.SCM.PerformTaskName.Content.ToString() != "    运  行    ")
                                {
                                    _systemConfigStatic.SCM.PerformTaskName.Content = "    运  行    ";
                                }
                                if (DialogHost.IsDialogOpen(PopUpTypes.Global.ToString())) DialogHost.Close(PopUpTypes.Global.ToString());
                            }, 0);
                            var serviceList = _temporaryStatic.LinkList.FirstOrDefault(x => x.ServiceName == "上位机状态");
                            if (serviceList != null) { serviceList.Status = false; }

                        }).ConfigureAwait(false);
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    $"启动任务异常：{ex}".RunLog(MessageLevelType.错误);
                    _temporaryStatic.IsRunStatus = false;
                    return false;
                }
            }
            _ = "设备链接失败!!!\r\n前往日志系统查看详细设备.".MessageDialogs(MessageLevelType.错误, true, Enums.PopUpTypes.Global);
            _taskToken.Cancel();
            CloseDevice();
            return false;
        }

        private void CloseDevice()
        {
            foreach (var item in _deviceConfig.DeviceList)
            {
                if (item.Communication == null)
                {
                    continue;
                }
                try
                {
                   var _msg = item.Communication.Close();
                    $"[释放Socket]：{_msg}".RunLog(MessageLevelType.信息);
                    item.Communication = null;
                }
                catch (Exception ex)
                {
                    $"释放异常：{ex}".RunLog(MessageLevelType.信息);
                }
            }
        }

        public bool RemoveTask(Context.DataContext model) => _taskcd.TryRemove($"{model.ServiceName}{model.TaskType.GetHashCode()}{model.DeviceType.GetHashCode()}{model.Address_Struct}{model.DeviceIndex}", out _);
        public void SwitchOFF() => _taskToken.Cancel();

        public async Task<bool> DeviceLink()
        {
            return await Task.Run(() => Parallel.ForEach(_deviceConfig.DeviceList, (x, _parallelLoopState) =>
            {
                try
                {
                    if (x.Index == 0 || string.IsNullOrEmpty(x.IPCOM) || x.Index == 999) { return; }
                    ICommunication com = null;
                    EndianTypes endianTypes = EndianTypes.Fins;
                    switch (x.DeviceType)
                    {
                        case DeviceTypes.NJ_FINS_PLC:
                            endianTypes = EndianTypes.Fins;
                            break;
                        case DeviceTypes.Modbus_TCP_ABCD:
                            endianTypes = EndianTypes.Modbus_ABCD;
                            break;
                        case DeviceTypes.Modbus_TCP_BADC:
                            endianTypes = EndianTypes.Modbus_BADC;
                            break;
                        case DeviceTypes.Modbus_TCP_DCBA:
                            endianTypes = EndianTypes.Modbus_DCBA;
                            break;
                        case DeviceTypes.Modbus_TCP_CDAB:
                            endianTypes = EndianTypes.Modbus_CDAB;
                            break;
                        case DeviceTypes.CIP_Omron:
                            endianTypes = EndianTypes.CIP_Omron;
                            break;
                    }
                    if (x.IsSocket)
                    {
                        com = new TCPCom(_systemConfigStatic.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, _taskToken, endianTypes);
                    }
                    else
                    {
                        com = new SerialPortCom(_systemConfigStatic.SCM.FinsIP, x.IPCOM, x.Port,
                            System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, x.DeviceType, x.Index, x.TaskType, x.ServiceName, _taskToken, endianTypes);
                    }
                    com.ReconnectDisconnection += Device_DropAlarms;
                    IDevices model = EquipmentFactory.NewSocketDevice(_systemConfigStatic.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, _taskToken, com);
                    if (model == null)
                    {
                        return;
                    }
                    bool? bools = model.Open();
                    if (bools != null && bools == true)
                    {
                        if (x.DeviceType == DeviceTypes.AND4531B_Scale
                        || x.DeviceType == DeviceTypes.TC06_Scale
                        ||x.DeviceType == DeviceTypes.TSC_L )
                        {
                            _ = model.Read();
                        }
                        x.Communication = model;
                    }
                    else
                    {
                        _parallelLoopState.Stop();
                        $"设备：[{x.TaskType}] 序号：[{x.Index}] IP：[{x.IPCOM}] 端口号：[{x.Port}] 连接失败".RunLog(MessageLevelType.错误);
                    }
                }
                catch (Exception ex)
                {

                    $"设备：[{x.TaskType}] 序号：[{x.Index}] IP：[{x.IPCOM}] 端口号：[{x.Port}] 连接异常".RunLog(MessageLevelType.错误);
                }
                
            }).IsCompleted);
        }

        private bool Device_DropAlarms(ICommunication com, int index, string ipcom, int port, DeviceTypes deviceTypes, TaskTypes taskType, string serviceName, CancellationTokenSource token)
        {
            try
            {
                DeviceClientModel device = _deviceConfig.DeviceList.FirstOrDefault(t => t.DeviceType == deviceTypes && t.IPCOM == ipcom && t.Index == index && t.Port == port && t.TaskType == taskType && t.ServiceName == serviceName);
                if (token.Token.IsCancellationRequested || device.Communication == null)
                {
                    return false;
                }
                device.Communication.Close();
                //if (com.Types == DeviceTypes.注_CP1WCIF41 || com.Types == DeviceTypes.补_CP1WCIF41)
                //{
                //    $"{ipcom} 注液泵通信断开，重启网络模块......".RunLog(MessageLevelType.警告);
                //    string[] ip = ipcom.Split('.');
                //    if (ip[2].Restart_CP1WCIF41_Module(ip[3]))
                //    {
                //        Thread.Sleep(10000);//延时10S等待重启完成
                //        $"重启完成，重新发送指令".RunLog(MessageLevelType.警告);
                //    }
                //    else
                //    {
                //        $"重启注液泵执行失败".RunLog(MessageLevelType.错误);
                //    }
                //}
                Thread.Sleep(500);
                if (device.Communication.Open())
                {
                    $"设备：[{deviceTypes}] 序号：[{index}] IP：[{ipcom}] 端口号：[{port}]---重连成功！".RunLog(MessageLevelType.成功);
                    return true;
                }
                Thread.Sleep(500);
                $"设备：[{deviceTypes}] 序号：[{index}] IP：[{ipcom}] 端口号：[{port}]---重连失败...".RunLog(MessageLevelType.错误);
            }
            catch (Exception ex)
            {
                Thread.Sleep(500);
                $"设备重连异常：{ex}".RunLog(MessageLevelType.错误);
            }
            return false;
        }

        /// <summary>
        /// 设备状态上传送
        /// </summary>
        /// <param name="service_name"></param>
        private void UpdateDeviceStatus(string service_name)
        {

            if (_temporaryStatic.DeviceStatus.ContainsKey(service_name))
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(sende =>
                {
                    var interaction = new OeeStatusInterface(DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
                    Dictionary<string, object> param = new Dictionary<string, object>
                {
                        { "machineNo", _parameterStatic.CollectionItemsParameter.EquipNum },
                        { "producttype", _parameterStatic.CollectionItemsParameter.ProductType.ToString() },
                };
                    while (!_taskToken.Token.IsCancellationRequested)
                    {
                        // 1:自动运行 , 2  待机, 3 报警,4 手动,5 故障状态,6 维修状态,7  急停状态                       
                        int device_status = _temporaryStatic.DeviceStatus[sende.ToString()];
                        int equipSign = device_status switch
                        {
                            var r when r == 1 => 1,
                            var r when r == 2 => 2,
                            var r when r == 5 => 3,
                            var r when r == 6 => 4,
                            var r when r == 7 => 5,
                            _ => 6,
                        };
                        Dictionary<string, object> parameter = new Dictionary<string, object>()
                    {
                            { "tenantID", _parameterStatic.CollectionItemsParameter.ProductionLineNo },//租户ID,//产线编号
                            { "equipCode", _parameterStatic.CollectionItemsParameter.EquipNum },//设备编号
                            { "operateId", _temporaryStatic.Mes_Account},//操作者ID
                            { "manualStatus", device_status == 4 ? 0 :1 },//手自动状态（0：手动；1：自动）
                            { "runStatus",  device_status == 1 ? 1 :0  },//运行状态（0：非运行；1：运行）
                            { "waitStatus",  device_status == 2 ? 1 :0 },//待机状态（0：非待机；1：待机）
                            { "faultStatus",  device_status == 5 ? 1 :0 },//故障状态（0：非故障；1：故障）
                            { "repairStatus",  device_status == 6 ? 1 :0 },//维修状态（0：非维修；1：维修）
                            { "stopStatus",  device_status == 7 ? 1 :0  },//急停状态（0：非急停；1：急停）
                            { "mesConnectStatus", 1 },//与MES通讯状态（0：状态异常；1：状态正常）
                            { "warnSign",  device_status == 3 ? 1 :0  },//报警指示灯状态（0：无报警指示；1：报警指示）
                            { "equipSign", equipSign },//设备状态指示牌（带反馈）（0：停机；1：运行；2：待机；3：故障；4：维修；5：急停；6：其它）
                            { "equipMesStatus", _parameterStatic.DecideParameter.EnableMES?0:1 },//设备MES状态（0：未屏蔽MES上位机或者扫码枪；1：屏蔽）
                            { "warningStatus", device_status == 3 ? 1 :0},//报警喇叭状态（0：喇叭停止；1：喇叭报警）
                    };

                        param.Add("parameter", parameter);
                        try
                        {
                            interaction.Interaction(_parameterStatic.MESParameter.BaseUrl + _parameterStatic.MESParameter.OeeStatusRouter,
                                _parameterStatic.MESParameter.OeeStatusTime,
                                _parameterStatic.MESParameter.OeeStatusNumber,
                                DateTime.Now, null, param);
                        }
                        catch (Exception)
                        {
                        }
                        param.Remove("parameter");
                        Thread.Sleep(_parameterStatic.RunParameter.DeviceStatusTime * 1000);
                    }
                }), service_name);
            }
        }
    }
}
